import sys
import common 

def simple_type(t):
	if t.endswith('byte') or t.endswith('short') or t.endswith('int') or  t.endswith('long'):
		t=1
	else:
		t=0
	return t


				
		
def print_getvar(cls,f,len_fix,all,no):	
	ret_type=common.get_ret_type(f[1])
	field_name=common.get_name(f[0])
	if f[2]!='' and not ret_type.endswith('*'):
		ret_type=ret_type+'*'

	print('//%s'%(f[3]))
	print('%s %s::Get%s()'%(ret_type,cls,field_name))
	if len_fix==0:
		p='&dummy'
	else:
		p='(char*)(this+1)'
		
	print('''
{
	      char*p=%s;      	
	'''%(p))
	
	
	for i in range(0,no):

			print('\t\tp+=((%s *)p)->Size();//%s'%(common.get_cls_name(all[i][1]),all[i][0]))
		
	t=common.get_result_type(f[1])
	if f[2]!='' and (t==1 or t==2):
		t=4
			
	if t==3:
		print('''
	    return (%s)p;
}'''%(ret_type))
	elif t==1:
		print('''
	    return ((%s*)p)->value;
}'''%(common.get_cls_name(f[1])))
	elif t==4:
		print('''
	    return ((%s)p);
}'''%(ret_type))
	else:	
		print('''
	    return ((%s*)p)->to_int();
}'''%(common.get_cls_name(f[1])))			
	
#if len(sys.argv)<2:
#     print("usage:")
#     exit(0)
#inf=sys.argv[1]
inf='dex-def.txt'

myfile = open(inf, "r")
fixed=[]
var=[]
l=[]
ll=[]
f=0
count=''
for line in (myfile):
	s=line.strip(' \t\n')
	if len(s)<1:
		continue
		
	if s.startswith('#'):
		if len(s)>1 and s.endswith('#'):
			#print(s)
			n=s[1:-1]
			n1=n.split(' ',1)
			#print(n)
			#print(n1)
			if len(n1)>1:
				name=common.get_cls_name(n1[0])
			else:
				name=common.get_cls_name(n)	
			fixed=[]
			var=[]
			
			l=[name,fixed,var]
			ll.append(l)
			f=0			
		continue 
	
	s1=s.split('\t',1)
	field=s1[0]
	s2=s1[1].split('\t',1)
	t=s2[0]


	if len(s2)>1:
		comment=s2[1]
	else:
		comment=''
		
	t1=t.split(' ',1)
	if len(t1)>1:
		t=t1[0].strip(' ')
		comment=comment+'('+t1[1]+')'	
				
	i=t.find('[')
	if i!=-1:
		count=t[i+1:-1]
		t=t[:i]
		if count=='':
			count='*'
	else:
		count=''
	if f==0:
		if simple_type(t)==0: #t=='String' or t.endswith('128')) or t=='encoded_value': 
			f=1
		elif count!='' and not count[0].isdigit():
			f=1
	

	if f==0:
		fixed.append([field,t,count,comment]) 
	else:
		var.append([field,t,count,comment])	

print('''
#include "util.h"
#include "dex-structs.h"
#include "dex-types.h"
#include "encoded-value.h"
#include "dex-class.h"
#include "dex-annotation.h"
#include "dex-string.h"
#include "dex-method.h"

''')		
for x in ll:
	s=x[0]
	

	i=0
	for y in x[2]:
		print_getvar(s,y,len(x[1]),x[2],i)						
		i=i+1
		
	print('''				
void %s::print()
{'''%(s))

	for y in x[1]:
		fmt=common.get_format(y[1])
		if y[2]=='':		
			print('\tprintf("\\n%s:%s",%s);'%(common.get_var_label(y[0]),fmt,y[0]))
		elif y[2]!='*':
			print('\tprintf("\\n%s:");'%(	common.get_var_label(y[0])))

			if y[2]=='abs(size)':
					print('\tint _size=size;')						
					print('\tif(_size<0) {_size=-_size;}')					
					sz='_size'      #print('\tfor(int i=0;i<_size;i++){')		
			else:
					sz=y[2]
		
			if y[1]=='ubyte':
				print('\tprint_mem32((char*)%s,0,%s);'%(y[0],sz))
			else:			
				print('\tfor(int i=0;i<%s;i++){'%(sz))									
				print('\t\tprintf("%s ",%s[i]);'%(fmt,y[0]))
				print('\t}')
		else:
			print('\t//FIXME: no size for array')
	
	if len(x[1])==0:
		p='&dummy'
	else:
		p='(char*)(this+1)'
	
	if len(x[2])>0:
		print('\tchar * p=%s;'%(p))	
	

		i=len(x[2])
		for y in x[2]:
			print('\tprintf("%s:");'%(common.get_var_label(y[0])))		

			if y[2]=='':
				print('\t((%s *)p)->print();//%s'%(common.get_cls_name(y[1]),y[0]))
				if i>1:
					print('\tp+=((%s *)p)->Size();'%(common.get_cls_name(y[1])))						
			elif y[2]!='*':

				if y[2]=='abs(size)':
					print('\tint _size=GetSize();')						
					print('\tif(_size<0) {_size=-_size;}')					
					sz='_size'     #print('\tfor(int i=0;i<_size;i++){')					
				else:
					
					print('\tint _%s=Get%s();'%(y[2],common.get_name(y[2])))			
					sz='_%s'%(y[2])	
				if y[1]=='ubyte':
					print('\tprint_mem32(p,0,%s);'%(sz))
				else:					
					print('\tfor(int i=0;i<%s;i++){'%(sz))
					print('\t\t((%s *)p)->print();'%(common.get_cls_name(y[1])))				
					print('\t\tp+=((%s *)p)->Size();'%(common.get_cls_name(y[1])))						
					print('\t}')
			else:
				print('\t//FIXME: no size for array')					
				
			i=i-1

		
	print('''
}''')

	print('''				
int %s::sprint(char * buffer)
{
	int len=0;'''%(s))

	for y in x[1]:
		fmt=common.get_format(y[1])
		if y[2]=='':		
			print('\tlen+=sprintf(buffer+len,"%s:%s",%s);'%(common.get_var_label(y[0]),fmt,y[0]))
		elif y[2]!='*':
			print('\tlen+=sprintf(buffer+len,"%s:");'%(	common.get_var_label(y[0])))
			if y[2]=='abs(size)':			
					print('\tint _size=%s;'%(y[2]))						
					print('\tif(_size<0) {_size=-_size;}')					
					sz='_size'      #print('\tfor(int i=0;i<_size;i++){')		
			else:
					sz=y[2]
		
			if y[1]=='ubyte':
				print('\tprint_mem32((char*)%s,0,%s);'%(y[0],sz))
			else:			
				print('\tfor(int i=0;i<%s;i++){'%(sz))									
				print('\t\tlen+=sprintf(buffer+len,"%s ",%s[i]);'%(fmt,y[0]))
				print('\t}')
		else:
			print('\t//FIXME: no size for array')	
	if len(x[1])==0:
		p='&dummy'
	else:
		p='(char*)(this+1)'
	
	if len(x[2])>0:
		print('\tchar * p=%s;'%(p))	
	

		i=len(x[2])
		for y in x[2]:
			print('\tlen+=sprintf(buffer+len,"%s:");'%(common.get_var_label(y[0])))		

			if y[2]=='':
				print('\tlen+=((%s *)p)->sprint(buffer+len);//%s'%(common.get_cls_name(y[1]),y[0]))
				if i>1:
					print('\tp+=((%s *)p)->Size();'%(common.get_cls_name(y[1])))						
			elif y[2]!='*':
				if y[2]=='abs(size)':		
					print('\tint _size=GetSize();')						
					print('\tif(_size<0) {_size=-_size;}')					
					sz='_size'     #print('\tfor(int i=0;i<_size;i++){')					
				else:
					
					print('\tint _%s=Get%s();'%(y[2],common.get_name(y[2])))			
					sz='_%s'%(y[2])	
				if y[1]=='ubyte':
					print('\tlen+=sprint_mem32(buffer+len,0,p,%s);'%(sz))
				else:					
					print('\tfor(int i=0;i<%s;i++){'%(sz))
					print('\t\tlen+=((%s *)p)->sprint(buffer+len);'%(common.get_cls_name(y[1])))				
					print('\t\tp+=((%s *)p)->Size();'%(common.get_cls_name(y[1])))						
					print('\t}')
			else:
				print('\t//FIXME: no size for array')					
			i=i-1

		
	print('''
	return len;
}''')

	print('''				
int %s::Size()
{
	int len;'''%(s))

	if len(x[1])>0:
		print('\tlen=sizeof(*this);')
	else:
		print('\tlen=0;')		
	
	if len(x[1])==0:
		p='&dummy'
	else:
		p='(char*)(this+1)'
	
	if len(x[2])>0:
		print('\tchar * p=%s;'%(p))	
	


		for y in x[2]:	

			if y[2]=='':
				print('\tlen+=((%s *)p)->Size();//%s'%(common.get_cls_name(y[1]),y[0]))				
			elif y[2]!='*':									
				if y[2]!='abs(size)':
					print('\tint _%s=Get%s();'%(y[2],common.get_name(y[2])))
					print('\tfor(int i=0;i<_%s;i++){'%(y[2]))			
				else:
					print('\tint _size=GetSize();')					
					print('\tif(_size<0) {_size=-_size;}')				
					print('\tfor(int i=0;i<_size;i++){')
				print('\t\tlen+=((%s *)p)->Size();'%(common.get_cls_name(y[1])))				
				print('\t\tp+=((%s *)p)->Size();'%(common.get_cls_name(y[1])))						
				print('\t}')	
			else:
				print('\t//FIXME: no size for array')
		
	print('''
	return len;
}''')

